package net.qiqbframework.modelling.domain;

import net.qiqbframework.messaging.annotation.MessageExecutableHandler;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * 聚合（根）模型。
 */
public interface AggregateModel<T> extends EntityModel<T> {

    /**
     * 获取建模聚合类型的 String 表示形式。默认情况下，这将为聚合类型的简单名称。
     *
     * @return The type of the aggregate
     */
    String type();

    /**
     * 获取给定 aggregate的当前版本号
     */
    Long getVersion(T target);


    /**
     * Gets the aggregate class based on given {@code declaredType}.
     *
     * @param declaredType the declared type of aggregate represented by {@link String}
     * @return the concrete aggregate class based on {@code declaredType}, if exists
     */
    default Optional<Class<?>> type(String declaredType) {
        return Optional.empty();
    }

    /**
     * Gets the declared aggregate type based on given class {@code type}.
     *
     * @param type the type of the aggregate
     * @return the declared aggregate type represented by {@link String}, if exists
     */
    default Optional<String> declaredType(Class<?> type) {
        return Optional.empty();
    }

    /**
     * Gets all types (concrete aggregate classes) of this aggregate.
     *
     * @return all types (concrete aggregate classes) of this aggregate
     */
    default Stream<Class<?>> types() {
        return Stream.empty();
    }


    default void addCommandHandler(MessageExecutableHandler messageHandlingMember) {
        throw new UnsupportedOperationException("not support add command handler");
    }

    default Map<Class<?>, List<MessageExecutableHandler>> allCommandHandlers() {
        return Collections.emptyMap();
    }


    default Stream<MessageExecutableHandler> commandHandlers(Class<? extends T> type) {
        return Stream.empty();
    }


    default Map<Class<?>, List<MessageExecutableHandler>> allCommandHandlerInterceptors() {
        return Collections.emptyMap();
    }

    /**
     * Gets command handler interceptors for provided {@code type} in this aggregate hierarchy.
     *
     * @param type the aggregate type in this hierarchy
     * @return a stream of command handler interceptors for provided {@code type}
     */
    default Stream<MessageExecutableHandler> commandHandlerInterceptors(Class<? extends T> type) {
        return Stream.empty();
    }

}
